Lesson 25   Audio & Video
As of LC 8.1.9, the play command on desktop supports: wav, aiff, au. The player object on desktop supports: wav, aiff, au, mp3, wma, avi, mpg, wmv. IOS & Android support: wav, mp3, aac, m4a, m4v, mp4. IOS also supports: aiff.

Expand File Support
* Windows. K-Lite Basic codec expands desktop support (includes LAV filters): aac, m4a, mp4, mov, flac, ogg. https://www.codecguide.com/download_kl.htm. Choose basic, click small mirror1/2 download link.
* Mac. Existing AVFoundation codec already supports most a/v formats.
* Linux. No sound support. Install VLC player (recommended)  https://www.videolan.org/vlc/#download or mPlayer http://www.mplayerhq.hu/design4/dload.html. VLC has versions to support most Linux distros with easy install. mPlayer download and install is more difficult using Synaptic, Suse, or commandline. CmdLine: 'sudo apt-get install mPlayer'.
A Linux player object bug remains unfixed in LC 8x to 9x series. 1st workaround is to downgrade to LC 7.1.4 to test and build with stacks that use audio & video in a player object. http://downloads.livecode.com/livecode/. 2nd workaround is to use shell() function in LC 8x to 9x series.
on mouseUp  --shell() examples
   put specialFolderPath("documents") &"/sample.mp4" into tPath
   get shell("mplayer -ontop -noborder -geometry 50%:50%" && tPath)  --mPlayer
   put the windowid of this stack into tID 
   --get shell("mpv -wid" && tID && "-ontop -geometry 50%:50% -quiet -start 12 -autofit 50%" && tPath)  --mPlayer
   --get shell("vlc -I dummy --play-and-exit --drawable-xid" && tID && tPath)  --VLC
end mouseUp

The AppStore no longer accepts LiveCode Community iOS builds. iOS builds for personal use must be on a Mac with Xcode installed
and set in edit > preferences, mobile support.

Add referenced audio and video files or folder containing files to standalone builds in file > standalone builder settings, "copy files" tab.


AUDIO
There are two main ways to access an audio file: 1) reference the sound by its file path, or 2) import the sound directly into a stack. The reference method is best with many large sound files. The import method is best with small sound files and prevents the file from getting lost or separated from the stack, but imports can't use a player object. Imports don't use a file path and must be wav, aiff, au.

 Play A Referenced Sound
Requires file path, can use player, for larger files, files stay separate from stack.

on mouseUp  --referenced sound
   set the playLoudness to "100"  --0 to 100% of system volume setting
   play "c:/windows/media/chimes.wav"  --referenced on disk
   wait until sound() = "done" with messages
   --
   put specialFolderPath("documents") &"/sounds/tada.wav" into tPath
   if there is a file tPath then play tPath  --referenced in documents, ensure valid file path
   wait until sound() = "done" with messages
   --
   if there is a file tPath then set the fileName of player 1 to tPath  --player can't use imported sound
   play player 1  --referenced to player object
end mouseUp

on mouseUp  --referenced
  put specialFolderPath("documents") &"/sounds/dogbark.mp3" into tPath
  if there is a file tPath then set the fileName of player 1 to tPath  --file path loads sound
  play player 1  --referenced to player
  wait until sound() = "done" with messages
  play (specialFolderPath("documents") &"/sounds/meow.wav")  --referenced to documents
end mouseUp

on mouseUp  --referenced sound
   local tPath
   set the itemDel to "/"
   put item 1 to -2 of the fileName of this stack &"/Sounds" into tPath  --sounds folder & stack at same folder level
   set the defaultFolder to tPath  --for files()
   get files()  --line list of sound files in the defaultfolder
   if it <> the text of me then set the text of me to it  --update sounds list
   play value(clickLine())  --reference to default folder
   wait until sound() = "done" with messages
end mouseUp

on mouseUp  --referenced sound
   local tPath
   set the itemDelimiter to "/"
   put item 1 to -2 of the fileName of this stack &"/Sounds/Boingg1.aiff" into tPath
   if there is a file tPath then play tPath  --reference to full filepath
   wait until sound() = "done" with messages  --plays one sound at a time
   --
   answer file "Select a sound to play..." with specialFolderPath("Documents") &"/LiveCode/Sounds/"  --select dialog
   if result() = "Cancel" or it <> empty then exit to top
   play it
end mouseUp

on mouseUp  --reference desktop, standalone, mobile
  if environment() = "development" then put (specialFolderPath("documents") &"/sounds/meow.wav") into tPath  --ide
  else if environment() = "standalone application" then put (specialFolderPath("resources") &"/sounds/meow.wav") into tPath  --standalone
  else if environment() = "mobile" then put (specialFolderPath("engine") &"/sounds/meow.wav") into tPath  --mobile
  if there is a file tPath then play tPath
end mouseUp

 Play An Imported Sound
No file path, can't use player, for smaller files, files are embedded in stack, import only wav, aiff, au.
To import a sound file into a stack: file > import as control > audio file.
To delete an imported sound: tools > project browser, expand to show audio clips, select file, click trash icon in LR or click backSpaceKey.

on mouseUp  --imported sound
  set the playLoudness to "100"  --0 to 100% of system volume setting
  play "Hello.aiff"  --import only .wav, .aiff, .au
end mouseUp

on mouseUp  --imported sound
  play "Tada.wav"  --in stack, import only .wav, .aiff, .au
  wait until sound() = "done" with messages
end mouseUp

 Mobile Devices Referenced Sound
On mobile devices, construct the path of the sound file using specialFolderPath("engine"). Use mobilePlaySoundOnChannel, or play <filepath> command. IOS & Android support: wav, mp3, aac, m4a, m4v, mp4. IOS also supports: aiff.

on PlaySound pSound  --mobile referenced sound
   if environment() <> "mobile" then exit PlaySound
   put specialfolderpath("engine") &"/Sounds/DogBark.mp3" into tPath
   mobilePlaySoundOnChannel tPath, "current", "now"  --or "queued", "next"
end PlaySound

put specialFolderPath("engine") &"/applause.mp3" into tPath
if there is a file tPath then play tPath

if environment() = "mobile" then play (specialFolderPath("engine") &"/hiscore.wav")  --mobile must reference to engine
else play "hiscore.wav"  --imported in stack

 More Examples
play (specialFolderPath("documents") &"/LiveCode/Sounds/Ray2.aiff")  --reference to folder in Documents
play (specialFolderPath("desktop") &"/Audio/Hello.aiff")  --reference to folder in Desktop
play "Elephant.aiff"  --imported sound in open stack
mobilePlaySoundOnChannel (specialFolderPath("engine") &"/Sounds/Chime03.wav"), "current", "now"  --must reference engine folder

play player "My Player"  --start
start player "My Player"  --start
play empty  --stop
play stop  --stop
stop player "My Player"  --stop, all valid syntax

set the visible of player 1 to "false"  --hide player, still works
set the showController of player 1 to "false"  --hide controller bar
set the showBadge of player 1 to "true"  --allow user to show/hide controller bar


VIDEO
 Play Only Referenced Video
Requires file path, must use player object, files stay separate from stack, supports: avi, mpg, wmv.
Expand video file support by installing an additional codec.
Video can be imported into a stack, but because these files are so large it is recommended they be referenced in the documents folder with a player object and not imported.

on mouseUp  --referenced video
   answer file "Choose a video to play:" with type "AVI, MPG, WMV|avi,mpg,wmv|"  --restrict file type
   if it = empty then exit to top
   lock screen
   set the fileName of player 1 to it  --load video, expands full size without lockLoc
   set the currentTime of player 1 to "0"  --beginning
   set the lockLoc of player 1 to "false"
   set the width of player 1 to round(the height of player 1 * (the formattedWidth of player 1 / the formattedHeight of player 1))  --aspect ratio
   set the lockLoc of player 1 to "true"
   play player 1
end mouseUp

--add video file(s) folder to standalone via the "Copy Files" tab in file > standalone builder settings.
on LoadSelectedVideo  --load video into player
   put selectedText(fld "Video Menu") into tName
   if environment() = "development" then put specialfolderpath("documents") &"/Videos/" & tName into tPath  --ide
   else if environment() = "standalone application" then put (specialFolderPath("resources") &"/Videos/" & tName into tPath  --standalone
   if there is a file tPath then set the fileName of player "MyVideo" to tPath  --load avi, mpg, wmv
   set the currentTime of player "MyVideo" to "0"  --beginning
end LoadSelectedVideo

 Mobile Devices Referenced Video
On mobile devices, construct the path of the sound file using specialFolderPath("engine"). Must use mobileControlCreate for native player, or play video command for full screen video. IOS & Android support: avi, mpg, mp4, m4v.

on mouseUp  --mobile video
  mobileControlCreate "Player", "MyPlayer"
  mobileControlSet "MyPlayer", "visible", true
  mobileControlSet "MyPlayer", "rect", "50,50,500,500"
  mobileControlSet "MyPlayer", "filename", specialFolderPath("engine") &"/movie2.avi"  --avi, mpg, mp4, m4v
  mobileControlDo "MyPlayer", "play"
end mouseUp

on openCard
  put the effective fileName of this stack into tPath
  set the itemDel to "/"
  put "extras/video1" into last item of tPath  --same folder as stack
  if there is a file tPath then set the fileName of player 1 to tPath  --referenced video
  set the rect of player 1 to the rect of this card  --display rect
end openCard

put specialFolderPath("engine") &"/movie1.mp4" into tPath  --mobile video
if there is a file tPath then play video tPath  --referenced, plays full screen

if environment() = "mobile" then play video (specialFolderPath("engine") &"/videos/intro.mpg")  --mobile engine reference
else play player 1 (specialfolderpath("documents") &"/videos/intro.mpg")  --documents reference
----